import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingDeque;


public class Main {
static BlockingDeque<Knoten> work;
static Maschen allMash; 
static Main me; 
static XmlToGraphParser parser;
	
	public static void main(String[] args){
		me = new Main();
		//TODO parser(graph)
			File file = new File("..\\testsuite\\crack\\germany.xml");
			parser = new XmlToGraphParser(file);
			ConcurrentHashMap<Integer, Knoten> graph = parser.getGraph();//new ConcurrentHashMap<Integer, Knoten>();
//			ConcurrentHashMap<Integer, Knoten> graph = giMeThat();
		// parser supplies a parsed Map for "allMash" and "work"
//			System.err.println(graph);
		allMash = new Maschen(graph);
		work = new LinkedBlockingDeque<Knoten>(graph.values());
		
//		for(int i=0; i<4; i++){
			Thread worker = new Thread(me.new Worker());
			worker.start();
			try {
				worker.join();
			} catch (InterruptedException e1) {}										// main will never become interrupted
//		}
		System.out.println("Anzahl Stromnetze: " + allMash.maschen.size());
//		File f = new File(".");
//		try {
//			System.out.println("cd: "+ f.getCanonicalPath());
//		} catch (IOException e) {}
}
	


private static ConcurrentHashMap<Integer, Knoten> giMeThat() {
	ConcurrentHashMap<Integer, Knoten> ret = new ConcurrentHashMap<Integer, Knoten>();
	Knoten a = new Knoten(0, 1);
	Knoten b = new Knoten(1, 1);
	Knoten c = new Knoten(2, 1);
	Knoten d = new Knoten(3, 2);
	Knoten e = new Knoten(4, 2);
	Knoten f = new Knoten(5, 3);
	Knoten g = new Knoten(6, 3);
	d.addPre(a);
	d.addPre(b);
	d.addPre(f);
	e.addPre(d);
	g.addPre(f);
	
	ret.put(a.getId(), a);
	ret.put(b.getId(), b);
	ret.put(c.getId(), c);
	ret.put(d.getId(), d);
	ret.put(e.getId(), e);
	ret.put(f.getId(), f);
	ret.put(g.getId(), g);
	
	return ret;
	}



public class Worker implements Runnable{
	
		@Override
		public void run() {
			while (!Thread.interrupted() && !work.isEmpty()){
				Knoten akt = work.pollFirst();  //krit
				if(akt == null) break;
				Mash aktMash = akt.getMash();
				List<Knoten> vorList = new CopyOnWriteArrayList<Knoten>();//akt.getVorganger();
				for (Knoten k : aktMash.getkList()) {
					vorList.addAll(k.getVorganger());
				}
				
				for(Knoten pre : vorList){
					List<Knoten> mashList= new CopyOnWriteArrayList<Knoten>();
					Mash preMash= pre.getMash();
					for(Knoten knBack: preMash.getkList()){
						if(!vorList.contains(knBack)){
							mashList.add(knBack);
							
						}
					}
					if (!mashList.isEmpty()){
					preMash.removeKnList(mashList);
					Mash neu = new Mash(pre.getCapacity(),mashList);
					allMash.add(neu);
					}
				}
			}
		}

	}
}